package o.gwtp.editor.client.editor;

import java.util.ArrayList;
import java.util.List;

import o.gwtp.editor.client.editor.EditorPresenter.EditorProxy;
import o.gwtp.editor.client.navigation.NavigationTabElement;
import o.gwtp.editor.client.navigation.NavigationTabEvent;
import o.gwtp.editor.client.navigation.NavigationTabEvent.NavigationTabHandler;

import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.gwtplatform.mvp.client.EventBus;
import com.gwtplatform.mvp.client.StandardProvider;
import com.gwtplatform.mvp.client.proxy.PlaceImpl;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.ProxyFailureHandler;
import com.gwtplatform.mvp.client.proxy.ProxyImpl;
import com.gwtplatform.mvp.client.proxy.ProxyPlaceImpl;

/**
 * @author Olivier Monaco
 */
public class EditorProxyImpl extends ProxyPlaceImpl<EditorPresenter> implements
    EditorProxy {
  public static class WrappedProxy extends ProxyImpl<EditorPresenter> {
    @Inject
    public WrappedProxy(Provider<EditorPresenter> presenter) {
      this.presenter = new StandardProvider<EditorPresenter>(presenter);
    }
  }

  private List<HandlerRegistration> handlers = new ArrayList<HandlerRegistration>();

  public EditorProxyImpl(EditorPresenterProvider presenter, String nameToken) {
    presenter.setProxy(this);
    this.proxy = new WrappedProxy(presenter);
    place = new PlaceImpl(nameToken);
  }

  @Override
  protected void bind(ProxyFailureHandler failureHandler,
      PlaceManager placeManager, EventBus eventBus) {
    super.bind(failureHandler, placeManager, eventBus);

    NavigationTabHandler h = new NavigationTabHandler() {
      @Override
      public void onCloseTab(final NavigationTabElement element) {
        getPresenter(new AsyncCallback<EditorPresenter>() {
          @Override
          public void onFailure(Throwable caught) {
            // TODO Manage error
          }

          @Override
          public void onSuccess(EditorPresenter result) {
            if (element == result) {
              unbind();
            }
          }
        });
      }

      @Override
      public void onRevealTab(NavigationTabElement element) {
      }
    };
    handlers.add(eventBus.addHandler(NavigationTabEvent.getType(), h));
  }

  void unbind() {
    for (HandlerRegistration handler : handlers) {
      handler.removeHandler();
    }
  }
}
